//
//  AIViewController.swift
//  TestIos
//
//  Created by 李亚东 on 2025/11/4.
//  Copyright © 2025 Liyadong. All rights reserved.
//

import UIKit
import SnapKit
import QuartzCore

@objc(AIViewController)
class AIViewController: UIViewController {

    // MARK: - UI Components
    private let tableView: UITableView = {
        let tableView = UITableView()
        tableView.backgroundColor = UIColor(red: 0.97, green: 0.97, blue: 0.97, alpha: 1.0)
        tableView.separatorStyle = .none
        tableView.keyboardDismissMode = .interactive
        return tableView
    }()
    
    private let chatInputView: ChatInputView = {
        let view = ChatInputView()
        return view
    }()
    
    private let stopButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("停止", for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = UIColor(red: 0.2, green: 0.6, blue: 1.0, alpha: 1.0)
        button.layer.cornerRadius = 18
        button.layer.masksToBounds = true
        button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 20)
        button.isHidden = true
        button.alpha = 0
        return button
    }()
    
    // MARK: - Properties
    private let viewModel = AIChatViewModel()
    
    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        self.title = "AI 聊天助手"
        
        setupUI()
        setupTableView()
        setupInputView()
        setupViewModel()
        
        // 监听键盘
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillShow(_:)),
            name: UIResponder.keyboardWillShowNotification,
            object: nil
        )
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillHide(_:)),
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
        viewModel.stopTypingAnimation()
    }
    
    // MARK: - Setup
    private func setupUI() {
        view.addSubview(tableView)
        view.addSubview(chatInputView)
        view.addSubview(stopButton)
        
        // 使用 SnapKit 设置布局
        tableView.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide)
            make.left.right.equalToSuperview()
            make.bottom.equalTo(chatInputView.snp.top)
        }
        
        chatInputView.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
            make.height.greaterThanOrEqualTo(56)
        }
        
        stopButton.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.bottom.equalTo(chatInputView.snp.top).offset(-16)
        }
        
        // 添加点击事件
        stopButton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)
    }
    
    private func setupTableView() {
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(ChatMessageCell.self, forCellReuseIdentifier: "ChatMessageCell")
        tableView.estimatedRowHeight = 80
        tableView.rowHeight = UITableView.automaticDimension
    }
    
    private func setupInputView() {
        chatInputView.delegate = self
    }
    
    private func setupViewModel() {
        viewModel.delegate = self
        // ViewModel 会自动添加欢迎消息并通知
    }
    
    // MARK: - Actions
    @objc private func keyboardWillShow(_ notification: Notification) {
        guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
              let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
            return
        }
        
        let keyboardHeight = keyboardFrame.height
        let safeAreaBottom = view.safeAreaInsets.bottom
        
        UIView.animate(withDuration: duration) {
            self.chatInputView.transform = CGAffineTransform(translationX: 0, y: -keyboardHeight + safeAreaBottom)
            self.tableView.contentInset.bottom = keyboardHeight
            self.tableView.scrollIndicatorInsets.bottom = keyboardHeight
        }
        
        scrollToBottom(animated: true)
    }
    
    @objc private func keyboardWillHide(_ notification: Notification) {
        guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
            return
        }
        
        UIView.animate(withDuration: duration) {
            self.chatInputView.transform = .identity
            self.tableView.contentInset.bottom = 0
            self.tableView.scrollIndicatorInsets.bottom = 0
        }
    }
    
    // 检查是否在底部（允许5pt的误差）
    private func isAtBottom() -> Bool {
        let contentHeight = tableView.contentSize.height
        let tableViewHeight = tableView.bounds.height
        let contentOffsetY = tableView.contentOffset.y
        let bottomOffset = contentHeight - tableViewHeight - contentOffsetY
        
        // 允许5pt的误差，避免因为浮点数精度问题判断不准确
        return bottomOffset <= 5
    }
    
    private func scrollToBottom(animated: Bool) {
        guard viewModel.messages.count > 0 else { return }
        let indexPath = IndexPath(row: viewModel.messages.count - 1, section: 0)
        
        // 使用 DispatchQueue 确保在布局更新后滚动
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            // 先更新布局
            self.tableView.layoutIfNeeded()
            // 再滚动到底部
            self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: animated)
        }
    }
    
    @objc private func stopButtonTapped() {
        viewModel.stopTypingAnimation()
    }
    
    private func showStopButton() {
        guard stopButton.isHidden else { return }
        stopButton.isHidden = false
        UIView.animate(withDuration: 0.3) {
            self.stopButton.alpha = 1.0
        }
    }
    
    private func hideStopButton() {
        guard !stopButton.isHidden else { return }
        UIView.animate(withDuration: 0.3, animations: {
            self.stopButton.alpha = 0
        }) { _ in
            self.stopButton.isHidden = true
        }
    }
    
}

// MARK: - UITableViewDataSource
extension AIViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.messages.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ChatMessageCell", for: indexPath) as! ChatMessageCell
        let message = viewModel.messages[indexPath.row]
        cell.configure(with: message)
        return cell
    }
}

// MARK: - UITableViewDelegate
extension AIViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
    }
    
    // 检测用户开始滚动
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        viewModel.updateScrollState(isScrolling: true, isAtBottom: isAtBottom())
    }
    
    // 检测用户滚动中
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // 实时更新滚动状态
        let isScrolling = scrollView.isDragging || scrollView.isDecelerating
        viewModel.updateScrollState(isScrolling: isScrolling, isAtBottom: isAtBottom())
    }
    
    // 检测用户结束滚动
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate {
            // 如果没有减速动画，立即更新状态
            viewModel.updateScrollState(isScrolling: false, isAtBottom: isAtBottom())
        }
    }
    
    // 检测滚动完全停止
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        // 滚动完全停止后，更新状态
        viewModel.updateScrollState(isScrolling: false, isAtBottom: isAtBottom())
    }
}

// MARK: - ChatInputViewDelegate
extension AIViewController: ChatInputViewDelegate {
    func chatInputView(_ inputView: ChatInputView, didSendMessage message: String) {
        // 通过 ViewModel 发送消息
        viewModel.sendMessage(message)
    }
}

// MARK: - AIChatViewModelDelegate
extension AIViewController: AIChatViewModelDelegate {
    func viewModelDidAddMessage(_ viewModel: AIChatViewModel, at indexPath: IndexPath) {
        // 添加新行
        tableView.insertRows(at: [indexPath], with: .fade)
        
        // 滚动到底部
        scrollToBottom(animated: true)
    }
    
    func viewModel(_ viewModel: AIChatViewModel, shouldUpdateCellAt indexPath: IndexPath, with content: String, shouldUpdateHeight: Bool) {
        // 更新 cell 内容
        // 如果 cell 可见，直接更新；否则会在 cellForRowAt 中自动更新
        if let cell = tableView.cellForRow(at: indexPath) as? ChatMessageCell {
            // 获取最新的消息对象来更新 cell
            let message = viewModel.messages[indexPath.row]
            cell.configure(with: message)
        }
        
        // 如果需要更新高度
        if shouldUpdateHeight {
            // 记录更新前的contentOffset，用于保持底部位置稳定
            let previousContentOffset = tableView.contentOffset
            let previousContentHeight = tableView.contentSize.height
            
            // 等待布局完成后再更新表格高度
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                
                // 禁用动画，让高度变化瞬间完成，减少视觉抖动
                CATransaction.begin()
                CATransaction.setDisableActions(true)
                
                // 强制 tableView 布局，确保 cell 高度已更新
                self.tableView.layoutIfNeeded()
                
                // 使用 beginUpdates/endUpdates 触发高度重新计算
                self.tableView.beginUpdates()
                self.tableView.endUpdates()
                
                CATransaction.commit()
                
                // 计算高度变化量
                let newContentHeight = self.tableView.contentSize.height
                let heightDelta = newContentHeight - previousContentHeight
                
                // 如果高度增加了，调整contentOffset保持底部cell位置稳定
                if heightDelta > 0 {
                    let newContentOffset = CGPoint(
                        x: previousContentOffset.x,
                        y: previousContentOffset.y + heightDelta
                    )
                    self.tableView.contentOffset = newContentOffset
                }
            }
        }
    }
    
    func viewModel(_ viewModel: AIChatViewModel, shouldScrollToBottom animated: Bool) {
        // 检查是否应该自动滚动
        if viewModel.shouldAutoScrollToBottom(isAtBottom: isAtBottom()) {
            scrollToBottom(animated: animated)
        }
    }
    
    func viewModel(_ viewModel: AIChatViewModel, typingAnimationDidChange isAnimating: Bool) {
        if isAnimating {
            showStopButton()
            // 禁用发送功能
            chatInputView.setSendEnabled(false)
        } else {
            hideStopButton()
            // 启用发送功能
            chatInputView.setSendEnabled(true)
        }
    }
}
